package com.snail.ron.design.singleton;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;

/**
 * @author xueguoping
 * @desc: TODO 反射破坏单例
 *
 * @date 2022/4/1211:13
 */
public class SingletonDestroyByReflect {
    public static void main(String[] args)throws Exception{
        reflectMethod();
    }
    //反射破坏
    private static void reflectMethod() throws Exception{
        //reflectHungryMethod();
        //reflectLazyMethod();
        reflectLazyMethod2();
    }

    //饿汉
    private static void reflectHungryMethod() throws Exception{
        SingletonOne singletonOne = null;
        SingletonOne singletonOneNew = null;

        singletonOne = SingletonOne.getInstance();
        Class<SingletonOne> singletonOneClass = SingletonOne.class;
        Constructor<SingletonOne> declaredConstructor = singletonOneClass.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        singletonOneNew = declaredConstructor.newInstance();
        System.out.println(singletonOne == singletonOneNew);
    }

    //懒汉
    private static void reflectLazyMethod() throws Exception{
        SingletonTwo singletonTwo = null;
        SingletonTwo singletonTwoNew = null;

        Class<SingletonTwo> singletonTwoClass = SingletonTwo.class;
        Constructor<SingletonTwo> declaredConstructor = singletonTwoClass.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);
        singletonTwoNew = declaredConstructor.newInstance();

        singletonTwo = SingletonTwo.getInstance();
        System.out.println(singletonTwo == singletonTwoNew);
    }

    //修改标志位
    private static void reflectLazyMethod2() throws Exception{
        SingletonTwo singletonTwo = null;
        SingletonTwo singletonTwoNew = null;

        Class<SingletonTwo> singletonTwoClass = SingletonTwo.class;
        Constructor<SingletonTwo> declaredConstructor = singletonTwoClass.getDeclaredConstructor();
        declaredConstructor.setAccessible(true);

        singletonTwoNew = declaredConstructor.newInstance();
        Field flag = singletonTwoClass.getDeclaredField("flag");
        flag.setAccessible(true);
        flag.set(singletonTwoNew,true);

        singletonTwo = SingletonTwo.getInstance();
        System.out.println(singletonTwo == singletonTwoNew);
    }
}
